﻿/*
 * DATAFLOWCORE
 * 
 
 * Copyright 2012 - Mindstorm Multitouch Limited

Author - Bertrand Nouvel

DataFlowCore is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

DataFlowCore is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Lesser Public License for more details.
*/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;

namespace DFlowCore
{
    public static class Log
    {

        
        private static bool eloginaccessible = false;
        private static EventLog elog = null;

        private static bool initdone = false;
        private static string logfilename = "dflow-log-alt.txt";
        //private static System.IO.FileStream debuglog = null;

        /*
        public class LogFileTraceListener : System.Diagnostics.TraceListener
        {
            public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id)
            {
                base.TraceEvent(eventCache, source, eventType, id);
            }
        }
        */


        /*
        <system.diagnostics>
    <trace autoflush="false" indentsize="4">
      <listeners>
        <add name="myListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="TextWriterOutput.log" />
        <remove name="Default" />
      </listeners>
    </trace>
  </system.diagnostics>
        */

        private static void OnInit()
        {
            if (System.Configuration.ConfigurationSettings.AppSettings.AllKeys.Contains("logfile"))
            {
                //System.Configuration.ConfigurationManager.    
                logfilename=System.Configuration.ConfigurationSettings.AppSettings["logfile"] as string;
            }
            if ((logfilename != null) && (logfilename.Length > 0))
            {
                //debuglog = new System.IO.FileStream(logfilename, System.IO.FileMode.CreateNew);
              //  System.Diagnostics.Debug.Listeners.Add(new TraceListener());
            }
            initdone = true;
        }

        private static EventLog Elog
        {
            get {
                if ((elog == null)&&(!eloginaccessible))
                {
                    elog = new EventLog();
                    bool sourceFound = false;
                    try
                    {
                        sourceFound = EventLog.SourceExists("DFlowCore");
                    }
                    catch (System.Security.SecurityException)
                    {
                        sourceFound = false;
                    }
                    if (!sourceFound)
                    {
                        try
                        {
                            EventLog.CreateEventSource("DFlowCore", "DFlowCore");
                        }
                        catch (System.Security.SecurityException)
                        {
                            elog.Dispose();
                            elog = null;
                            eloginaccessible = true;
                            return null;
                        }
                    }

                    elog.Source = "DFlowCore";
                    elog.EnableRaisingEvents = true;
                }
                return elog;
            }
        }

        public delegate void LoggerDelegate(string s) ;

        public static LoggerDelegate OnDebug;
        public static void Debug(string s,int MV=3)
        {
            if (!initdone) OnInit();

            System.Diagnostics.Debug.IndentLevel = 3;
            System.Diagnostics.Debug.Print("[DBG]"+s);
            System.Diagnostics.Debug.IndentLevel += 1;
            StackTrace st = new StackTrace(true);
            int mv = st.FrameCount;
            if (mv > (1+MV)) mv = (1+MV);
            for (int i = 1; i < mv; i++)
            {
                StackFrame sf = st.GetFrame(i);
                System.Diagnostics.Debug.Print(System.String.Format("{0}:{1}:{2}", System.IO.Path.GetFileName(sf.GetFileName()), sf.GetFileLineNumber(), sf.GetMethod()));
            }
            System.Diagnostics.Debug.IndentLevel -= 1;


            if (OnDebug != null) { OnDebug(s); }
        }

        public static LoggerDelegate OnInfo;
        public static  void Info(string s, int MV=3)
        {
            if (!initdone) OnInit();

            System.Diagnostics.Debug.IndentLevel = 2;
            System.Diagnostics.Debug.Print("[NFO]" + s);

            System.Diagnostics.Debug.IndentLevel += 1;
            StackTrace st = new StackTrace(true);
            int mv = st.FrameCount;
            if (mv > (1 + MV)) mv = (1 + MV);
            for (int i = 1; i < mv; i++)
            {
                StackFrame sf = st.GetFrame(i);
                System.Diagnostics.Debug.Print(System.String.Format("{0}:{1}:{2}", System.IO.Path.GetFileName(sf.GetFileName()), sf.GetFileLineNumber(), sf.GetMethod()));
            }
            System.Diagnostics.Debug.IndentLevel -= 1;


            if (OnInfo != null) { OnInfo(s); }
        }


        public static LoggerDelegate OnWarning;
        public static  void Warning(string s, int MV=3)
        {
            if (!initdone) OnInit();

            System.Diagnostics.Debug.IndentLevel = 1;
            System.Diagnostics.Debug.Print("[WRN]" + s);
            ElogWriteEntry( s, System.Diagnostics.EventLogEntryType.Warning);

            System.Diagnostics.Debug.IndentLevel += 1;
            StackTrace st = new StackTrace(true);
            int mv = st.FrameCount;
            if (mv > (1 + MV)) mv = (1 + MV);
            for (int i = 1; i < mv; i++)
            {
                StackFrame sf = st.GetFrame(i);
                System.Diagnostics.Debug.Print(System.String.Format("{0}:{1}:{2}", System.IO.Path.GetFileName(sf.GetFileName()), sf.GetFileLineNumber(), sf.GetMethod()));
            }
            System.Diagnostics.Debug.IndentLevel -= 1;


            if (OnWarning != null) { OnWarning(s); }
        }

        public static void ElogWriteEntry(string s, System.Diagnostics.EventLogEntryType t) {
            if (elog == null)
            {
                if (Elog == null) return;
            }
            Elog.WriteEntry(s,t);
        }

        public static LoggerDelegate OnError;
        public static void Error(string s)
        {
            if (!initdone) OnInit();

            System.Diagnostics.Debug.IndentLevel = 0;
            System.Diagnostics.Debug.Print("[ERR]" + s);

            System.Diagnostics.Debug.IndentLevel += 1;
            StackTrace st = new StackTrace(true);
            for (int i = 0; i < st.FrameCount; i++)
            {
                StackFrame sf = st.GetFrame(i);
                System.Diagnostics.Debug.Print(System.String.Format("{0}:{1}:{2}", System.IO.Path.GetFileName(sf.GetFileName()), sf.GetFileLineNumber(), sf.GetMethod()));
            }
            System.Diagnostics.Debug.IndentLevel -= 1;

            ElogWriteEntry( s, System.Diagnostics.EventLogEntryType.Error);
            if (OnError != null) { OnError(s); }
        }

    }
}
